;;; xwl-misc.el --- external elisp extensions

;; Copyright (C) 2007, 2008, 2009 William Xu

;; Author: William Xu <william.xwl@gmail.com>

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; if not, write to the Free Software
;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
;; 02110-1301 USA

;;; Code:

;;; TeX Reated

(condition-case nil

;; - 插入 section, chapter 等: C-c C-s
;; - 插入 envrionment 如 itemize 等: C-c C-e
;; - 插入 macro: C-c RET
;; - 插入各种字体, 或改变选区域字体: C-c C-f *
;; - 快速插入 \item: C-c C-j

(load "auctex.el" nil t t)

(setq TeX-auto-save t)
(setq TeX-parse-self t)
(setq-default TeX-master nil)

(defun xwl-latex-mode-hook ()
  (smart-operator-mode 1)
  ;; (set (make-local-variable 'outline-regexp) "\%\%\%+ ")
  ;; (outline-minor-mode -1)

  ;; (define-key LaTeX-mode-map (kbd "<C-up>") 'TeX-command-master)
  (define-key LaTeX-mode-map (kbd "<backtab>") 'read-completer-latex)
  (define-key LaTeX-mode-map (kbd "$") 'skeleton-pair-insert-maybe)
  (define-key LaTeX-mode-map (kbd "C-c C-j") (lambda ()
                                               (interactive)
                                               (insert "\\item\n\n")
                                               (indent-according-to-mode))))

(add-hook 'LaTeX-mode-hook 'xwl-latex-mode-hook)

;; (require 'latex)
;; (remove-hook 'LaTeX-mode-hook 'outline-minor-mode-on)

;; Preview Support
;; ---------------

;; ,----[ Typical Error ]
;; | ! DviPS sentinel: Opening input file: no such file or directory
;; `----

;; Solution: on Mac OS X, if you have installed MacTeX and fink, be
;; careful not messing with them!! You should always use commands(latex,
;; dvips, dvipng, etc) installed by MacTeX(under "/usr/texbin") ! Check
;; your `exec-path' and value of (getenv "PATH"), make sure
;; "/usr/texbin" is in front of "/sw/bin", you can run "$ which dvips"
;; to find out.
;;
;; However, I find that outputing to pdf with xelatex is a lot faster
;; than the preview process!!  So after all theses efforts for enabling
;; preview, I would rather use xelatex as usual.

;; (load "preview-latex.el" nil t t)

(error nil)

)


;;; Chinese Wubi Input Method

(require 'wubi)
(register-input-method
 "chinese-wubi" "Chinese" 'quail-use-package "wubi" "wubi")

(setq wubi-phrases-file "~/.wubi-phrases.el")

(ignore-errors (wubi-load-local-phrases))
(setq default-input-method "chinese-wubi")

(setq xwl-input-methods
      '("chinese-wubi"
        "japanese"
        "japanese-katakana"
        "chinese-py")
      xwl-current-input-methods xwl-input-methods)

(defun xwl-cycle-input-method ()
  "Cycle `xwl-input-method-alist'."
  (interactive)
  (if (null (cdr xwl-current-input-methods))
      (setq xwl-current-input-methods xwl-input-methods)
    (setq xwl-current-input-methods (cdr xwl-current-input-methods)))
  (set-input-method (car xwl-current-input-methods)))

(setq xwl-traditional-p t)

;; (load "wubi")
;; (load "wubi-rules")

(defun xwl-toggle-simplified/traditional-input-method ()
  (interactive)
  (setq xwl-traditional-p (not xwl-traditional-p))
  (if xwl-traditional-p
      (progn
        (load "wubi-b5")
        (load "wubi-rules-b5")
        (setq wubi-phrases-file "~/.wubi-phrases-b5.el")
        (wubi-load-local-phrases))
    (load "wubi")
    (load "wubi-rules")
    (setq wubi-phrases-file "~/.wubi-phrases.el")
    (wubi-load-local-phrases)))

(global-set-key (kbd "C-SPC") 'toggle-input-method)
(global-set-key (kbd "C-/") 'xwl-cycle-input-method)

;; (global-set-key (kbd "C-?") 'xwl-cycle-input-method)
(global-set-key (kbd "C-,") 'wubi-toggle-quanjiao-banjiao)
(global-set-key (kbd "C-c m W") 'wubi-load-local-phrases)


;;; BBDB

;; bbdb TODO
(ignore-errors
  (progn
(require 'bbdb)
(bbdb-initialize)

(setq bbdb-north-american-phone-numbers-p nil)
(setq bbdb-user-mail-names
      (regexp-opt '("willam.xwl@gmail.com"
                    "willam.xwl@hotmail.com")))
(add-hook 'gnus-startup-hook 'bbdb-insinuate-gnus)
(add-hook 'mail-setup-hook 'bbdb-insinuate-sendmail)

(setq bbdb-complete-name-allow-cycling t
      bbdb-use-pop-up nil
      bbdb-file-coding-system 'utf-8
      ;; bbdb-quiet-about-name-mismatches t
      )

(define-key bbdb-mode-map (kbd "TAB") 'bbdb-toggle-records-display-layout)

(defun xwl-bbdb ()
  (interactive)
  (if (get-buffer "*BBDB*")
      (switch-to-buffer "*BBDB*")
    (bbdb "" nil)
    (other-window 1)
    (delete-other-windows)))

(defun my-bbdb-search (field str)
  "Search records whose FIELD matches STR."
  (interactive
   (list
    (ido-completing-read
     "Search: "
     (append (mapcar (lambda (el) (car el)) (bbdb-propnames))
             '("name")))
    (read-string "Match: ")))
  (if (string= field "name")
      (bbdb-name str nil)
    (let ((matches '())
          (case-fold-search bbdb-case-fold-search)
          (invert (bbdb-search-invert-p)))
      (when (stringp field)
        (setq field (intern field)))
      (mapc
       (lambda (record)
         (condition-case nil
             (let ((matchedp
                    (string-match
                     str
                     (cdr (assoc field (bbdb-record-raw-notes record))))))
               (when (or (and (not invert) matchedp)
                         (and invert (not matchedp)))
                 (setq matches (append matches (list record)))))
           (error nil)))
       (bbdb-records))
      (bbdb-display-records matches))))

(defun my-bbdb-create (name)
  "Add a new entry to the bbdb database.

This is different from `bbdb-create', where `my-bbdb-create' only
prompts for name field."
  (interactive "sName: ")
  (let ((record
         (vector name "" nil nil nil nil nil nil
                 (make-vector bbdb-cache-length nil))))
    (bbdb-invoke-hook 'bbdb-create-hook record)
    (bbdb-change-record record t)
    (bbdb-display-records (list record))))

(defun my-bbdb-display-all ()
  (interactive)
  (bbdb-display-records (bbdb-records)))

(define-key bbdb-mode-map (kbd "a") 'my-bbdb-display-all)
(define-key bbdb-mode-map (kbd "\/") 'my-bbdb-search)

))


;;; Misc misc

(require 'boxquote)
(global-set-key (kbd "C-c b r") 'boxquote-region)
(global-set-key (kbd "C-c b t") 'boxquote-title)
(global-set-key (kbd "C-c b f") 'boxquote-describe-function)
(global-set-key (kbd "C-c b v") 'boxquote-describe-variable)
(global-set-key (kbd "C-c b k") 'boxquote-describe-key)
(global-set-key (kbd "C-c b !") 'boxquote-shell-command)

;; (require 'rect-mark)
(require 'redo)
(require 'goto-last-change)

(when (< emacs-major-version 23)
  (require 'highlight-tail)
  (setq highlight-tail-colors
        '(("#bc2525" . 0)))
  ;;'(("#d8971d" . 0) ("#ddee1f" . 20)))
  (highlight-tail-reload)
  )

(require 'pack-windows)
(global-set-key (kbd "C-c m p") 'pack-windows)

;; debian
(require 'debian-bug)
(require 'apt-sources)

;; (require 'css-mode)

(require 'cmake-mode)
(setq auto-mode-alist
      (append '(("CMakeLists\\.txt\\'" . cmake-mode)
                ("\\.cmake\\'" . cmake-mode))
              auto-mode-alist))


;; (require 'bracketphobia)
(require 'srfi)

;; (require 'vc-bzr)

(require 'vc-darcs)
(add-to-list 'vc-handled-backends 'DARCS)
(setq vc-darcs-mail-address "William Xu <william.xwl@gmail.com>")

(require 'dired-isearch)
(define-key dired-mode-map (kbd "C-s") 'dired-isearch-forward)
(define-key dired-mode-map (kbd "C-r") 'dired-isearch-backward)
(define-key dired-mode-map (kbd "ESC C-s") 'dired-isearch-forward-regexp)
(define-key dired-mode-map (kbd "ESC C-r") 'dired-isearch-backward-regexp)

(require 'template)
(setq template-default-directories
      (append '("~/.templates")
              template-default-directories)
      template-date-format "%02m-%02d-%Y %02H:%02M:%02S"
      template-auto-insert t)
(setq template-expansion-alist
      '(("nick_name" (insert "xwl"))))
(template-initialize)

(defadvice template-new-file (around inhibit-less)
  "Inhibit `xwl-toggle-find-file-less' temporarily."
  (let ((less-on? (memq 'less-minor-mode-on find-file-hook)))
    (when less-on?
      (xwl-toggle-find-file-less))
    ad-do-it
    (when less-on?
      (xwl-toggle-find-file-less))))

(ad-activate 'template-new-file)

(require 'screen-lines)
(screen-lines-mode 1)
(setq screen-lines-minor-mode-string nil)

;; repair some missed keys on console
;; (require 'wx-key)


(require 'nuke-trailing-whitespace)
(defun nuke-trailing-whitespace-check-mode ()
  "Redefinition. Generally don't bother me!"
  (not (memq major-mode
             nuke-trailing-whitespace-never-major-modes)))

;; write-file-hooks must return nil if success.
(defun xwl-write-file-hook ()
  (xwl-update-date)
  (unless (string= (buffer-file-name) qterm-log-file)
    (nuke-trailing-whitespace)))

(add-hook 'write-file-hooks 'xwl-write-file-hook)


(require 'wordnet)
(add-hook 'wordnet-mode-hook 'less-minor-mode-on)


;;; disabled now
(when nil
;; msf-abbrev
(require 'msf-abbrev)
(setq msf-abbrev-verbose nil)
(setq msf-abbrev-root "~/.emacs.d/mode-abbrevs")
(msf-abbrev-load)
)

;; qterm
(require 'qterm)
(setq qterm-faces '(""
                    ;; "朗声" "鬼叫" "喃喃" "轻声" "一声大喝" "大叫"
                    ;; "柔柔" "大吼"
                    ))

(setq qterm-signature
      '(lambda ()
         (format "\n\n%s--\n%s%s"
                 ansit-color-magenta
                 (ansi-color-filter-apply
                  (shell-command-to-string "fortune"))
                 ansit-color-close)))

;; term, bbs
(defun xwl-bbs-heartbeat ()
  "Switch to *terminal* and move up and down once to keep bbs connection
alive every some minutes."
  (interactive)
  (mapc (lambda (i)
          (let ((buf (get-buffer i)))
            (when buf
              (with-current-buffer buf
                (term-send-up)
                (term-send-down)))))
        '("*ansi-term*" "smth" "mit")))

(run-at-time t 60 'xwl-bbs-heartbeat)

;;; (autoload 'easy-todo-mode "easy-todo")
(require 'easy-todo)
(add-to-list 'auto-mode-alist
             '("todo" . easy-todo-mode))
(global-set-key (kbd "<f8>") (lambda () (interactive) (find-file "~/notes/todo")))

(eval-after-load 'doc-view
  (add-hook 'doc-view-mode-hook 'less-minor-mode-on))

(require 'pabbrev)
(setq pabbrev-idle-timer-verbose nil)
(global-pabbrev-mode 1)

;; (load "/sw/share/emacs/site-lisp/ledger/ledger.el")

;; (load "~/repo/git/general/william/cwit.el")
;; (autoload 'cwit "cwit")

;; (global-set-key (kbd "<f4>") 'cwit)
;; (setq cwit-update-interval 120)
;; (setq cwit-use-local t)


(autoload 'dashboard "dashboard")
(add-hook 'dashboard-mode-hook 'less-minor-mode-on)

(require 'dashboard-tenseijingo)

;; (setq tramp-verbose 10)
;; "M-x tramp-submit-bug".
;; (setq tramp-debug-buffer t)
(ignore-errors
  (progn

(require 'mmm-auto)
(require 'mmm-sample)
(setq mmm-global-mode 'maybe)
(setq mmm-classes-alist
      (append '((text-html :submode html-mode
                           :front "<html>"
                           :front-offset (beginning-of-line 0)
                           :back "</html>"
                           :back-offset (end-of-line 1)
                           :face mmm-code-submode-face)
                (c-in-scheme :submode c-mode ; in chicken scheme
                              :front "#>"
                              :front-offset (beginning-of-line 0)
                              :back "<#"
                              :back-offset (end-of-line 1)
                              :face mmm-code-submode-face)
                )
              mmm-classes-alist))

(setq mmm-mode-ext-classes-alist
      '((message-mode nil text-html)
        (gnus-article-edit-mode nil text-html)
        (text-mode nil text-html)
        ;; (scheme-mode nil c-in-scheme)
        ))

;; (setq mmm-global-classes
;;       (append '(text-html)
;;               mmm-global-classes))

(defun xwl-mmm-refresh ()
  "Re-apply mmm-mode when buffer contents have been modified."
  (when (and mmm-mode (buffer-modified-p))
    (mmm-apply-all)))

(add-hook 'post-command-hook 'xwl-mmm-refresh)

))

;; wikipedia-mode
(add-to-list 'auto-mode-alist '(".wikipedia" . wikipedia-mode))
(add-hook 'wikipedia-mode-hook 'auto-fill-mode)
(add-hook 'wikipedia-mode-hook (lambda ()
                                 (local-unset-key (kbd "M-n"))
                                 (local-unset-key (kbd "M-p"))
                                 (local-unset-key (kbd "C-c r"))
                                 ))

(when (featurep 'emms)

  (defadvice find-file-noselect (around config-drag-n-drop activate)
    "配置文件 drag-n-drop 行为。"
    (let ((file (ad-get-arg 0)))

      ;; 添加音乐、视频文件至 EMMS
      (when (string-match (emms-player-get emms-player-mplayer 'regex) file)
        (emms-add-file file)
        (unless emms-player-playing-p
          (with-current-emms-playlist
           (goto-char (point-max))
           (forward-line -1)
           (emms-playlist-mode-play-smart)))
        (error (format "File `%s' opened in EMMS" file)))

      ;; 粘贴邮件附件
      (save-excursion
        (goto-char (point-max))         ; for handling mmm-mode
        (when (eq major-mode 'message-mode)
          (insert
           (format
            "<#part type=\"%s\" filename=\"%s\" disposition=attachment>
<#/part>"
            (mm-default-file-encoding file)
            file))
          (error (format "File `%s' attached" file))))

      ad-do-it))

  )

(eval-after-load 'tramp
  '(progn
     (when (boundp 'tramp-default-proxies-alist)
       (add-to-list 'tramp-default-proxies-alist
		    '("172.16.89.129" "\\`root\\'" "/ssh:%h:"))
     )))

(require 'generic-apt-install)
(add-hook 'generic-apt-mode-hook 'less-minor-mode-on)

(setq generic-apt-select-methods
      '((apt-get "ssh 172.16.89.129 sudo apt-get")
        (fink "sudo fink")))

(add-to-list 'auto-mode-alist
             '("macbluetelnet.*\\(\\.h\\|\\.mm\\|\\.m\\)$" . objc-mode))


(autoload 'finkinfo-mode "finkinfo-mode")
(add-to-list 'auto-mode-alist '("\\.info$" . finkinfo-mode))

(require 'bracketphobia)
;; (remove-hook 'find-file-hook 'bracketphobia-hide)

(when xwl-at-company-p
  (setq url-proxy-services
        `(("http" . ,(format "%s:%d" xwl-proxy-server xwl-proxy-port))))

  ;; redirect
  (let ((cmd "q:/usr/desproxy/desproxy.exe"))
    (mapcar (lambda (i)
              (let ((host (nth 0 i))
                    (port (nth 1 i))
                    (local-port (nth 2 i)))
                (xwl-shell-command-asynchronously
                 (format "%s %s %d %s %d %d"
                         cmd host port xwl-proxy-server xwl-proxy-port local-port))))
            ;; host port localport
            '(("irc.debian.org" 6669 16669)
              ("irc.freenode.net" 6667 16667)
              ("dict.org" 2628 12628))))

  )

;; maximize frame

(case window-system
  ((mac)
   (require 'maxframe)
   (setq mf-display-padding-width 0)
   (setq mf-display-padding-height (- mf-display-padding-height 10))

   (setq mf-max-width 1900)

   ;; (add-hook 'window-setup-hook 'maximize-frame t)
   ;; (maximize-frame)
   )
  ((w32)
   (w32-send-sys-command #xf030)))

(provide 'xwl-misc)

;;; xwl-misc.el ends here
